#include "gtest/gtest.h"
#include "../deck.h"
#include <iostream>

TEST(CardTest, CardValue)
{
	EXPECT_EQ(1, Card(Card::Ace, Card::Clubs).Value());
	EXPECT_EQ(11, Card(Card::Jack, Card::Clubs).Value());
	EXPECT_EQ(14, Card(Card::Ace, Card::Diamonds).Value());
	EXPECT_EQ(27, Card(Card::Ace, Card::Hearts).Value());
	EXPECT_EQ(53, Card(Card::JokerA, Card::Diamonds).Value());
	EXPECT_EQ(53, Card(Card::JokerB, Card::Clubs).Value());
}

TEST(DeckTest, DeckInitialized)
{
	std::list<int> compare_list;
	int compare_ints[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,53};
	compare_list.assign( compare_ints, compare_ints + sizeof(compare_ints) / sizeof(int) );

	EXPECT_TRUE(compare_list == Deck().GetValues());
}

TEST(DeckTest, MoveCard)
{
	std::list<int> compare_list;
	Deck deck;

	deck.Move(Card(Card::Ace, Card::Clubs), 1);	
	int compare_ints1[]={2,1,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,53};
	compare_list.assign( compare_ints1, compare_ints1 + sizeof(compare_ints1) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());

	deck.Move(Card(Card::Ace, Card::Clubs), 2);	
	int compare_ints2[]={2,3,4,1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,53};
	compare_list.assign( compare_ints2, compare_ints2 + sizeof(compare_ints2) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());
	
	deck.Move(Card(Card::JokerA, Card::Clubs), 1);	
	int compare_ints3[]={2,3,4,1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,53};
	compare_list.assign( compare_ints3, compare_ints3 + sizeof(compare_ints3) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());
	
	deck.Move(Card(Card::JokerB, Card::Spades), 2);	
	int compare_ints4[]={2,53,3,4,1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53};
	compare_list.assign( compare_ints4, compare_ints4 + sizeof(compare_ints4) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());
}

TEST(DeckTest, TripleCut)
{
	std::list<int> compare_list;
	Deck deck;

	deck.Triple_Cut();
	int compare_ints1[]={53,53,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52};
	compare_list.assign( compare_ints1, compare_ints1 + sizeof(compare_ints1) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());

	deck.Move(Card(Card::JokerA, Card::Clubs), 1);	
	deck.Triple_Cut();
	int compare_ints2[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,53};
	compare_list.assign( compare_ints2, compare_ints2 + sizeof(compare_ints2) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());
	
	deck.Move(Card(Card::JokerB, Card::Clubs), 7);	
	deck.Move(Card(Card::JokerA, Card::Clubs), 50);	
	deck.Triple_Cut();
	int compare_ints3[]={50,51,52,53,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,53,1,2,3,4,5,6};
	compare_list.assign( compare_ints3, compare_ints3 + sizeof(compare_ints3) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());
}

TEST(DeckTest, CountCut)
{
	std::list<int> compare_list;
	Deck deck;
	
	deck.Move(Card(Card::Ace, Card::Clubs), 53);
	deck.Count_Cut();
	int compare_ints1[]={3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,53,2,1};
	compare_list.assign( compare_ints1, compare_ints1 + sizeof(compare_ints1) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());
	
	deck.Move(Card(Card::Three, Card::Clubs), 53);
	deck.Count_Cut();
	int compare_ints2[]={7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,53,2,1,4,5,6,3};
	compare_list.assign( compare_ints2, compare_ints2 + sizeof(compare_ints2) / sizeof(int) );

	EXPECT_TRUE(compare_list == deck.GetValues());
}

TEST(DeckTest, OutputLetter)
{
	Deck deck;

	EXPECT_EQ('B', deck.Output_Letter());

	deck.Move(Card(Card::Ace, Card::Clubs), 1);
	EXPECT_EQ('C', deck.Output_Letter());
	
	deck.Move(Card(Card::Ace, Card::Clubs), 10);
	deck.Move(Card(Card::Two, Card::Clubs), 10);
	deck.Move(Card(Card::Three, Card::Clubs), 10);
	EXPECT_EQ('H', deck.Output_Letter());
}

TEST(DeckTest, ShuffleDeck)
{
	Deck deck;

	deck.Shuffle();

	std::cout << " - Ensure the deck values below are shuffled -\n";

	std::list<int> shuffle_list = deck.GetValues();
	std::list<int>::const_iterator shuffle_iter;
	for (shuffle_iter = shuffle_list.begin(); shuffle_iter != shuffle_list.end(); ++shuffle_iter)
	{
		std::cout << " " << (*shuffle_iter);
	}	
	std::cout << "\n";
}
